package com.mijie.homi.ns.service;

import java.util.Date;

import net.sf.json.JSONObject;

import org.apache.mina.core.session.IoSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mijie.core.ApplicationProperties;
import com.mijie.homi.common.constant.CategoryCode;
import com.mijie.homi.common.constant.TypeCode;
import com.mijie.homi.common.domain.PushMessage;
import com.mijie.homi.common.domain.chat.ChatMessage;
import com.mijie.homi.common.domain.session.Session;
import com.mijie.homi.common.domain.user.Friend;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.domain.user.UserExtInfo;
import com.mijie.homi.common.protocol.HomiProtocol;
import com.mijie.homi.common.util.HomiUtil;
import com.mijie.homi.ns.core.HomiServer;
import com.mijie.homi.ns.dao.ChatMessageDao;
import com.mijie.homi.ns.domain.Constants;
import com.mijie.homi.ns.traffic.MessageRouter;
import com.mijie.util.Helper;

@Service
public class ChatService {

	@Autowired
	private ChatMessageDao dao;
	@Autowired
	private UserService userService;
	@Autowired
	private FriendService friendService;
	@Autowired
	private SessionService sessionService;
	@Autowired
	private NotifyService notifyService;
	@Autowired
	private MemcacheService mcs;
	@Autowired
	private HomiServer homiServer;
	@Autowired
	private MessageRouter messageRouter;
	
	public int saveChatMessage(ChatMessage message){
		return dao.saveChatMessage(message);
	}
	
	public int deleteChatMessage(String[] ids){
		return dao.deleteChatMessage(ids);
	}
	
	public boolean blockingMessage(int userId,int intruder){
		return dao.blockingMessage(userId, intruder);
	}
	
	public void sendChatMessage(int sender,JSONObject json){
		String msg = json.getString("message").trim();
		if(msg.length()>Constants.MAX_WORD_CHAT)
			json.put("message", msg.substring(0, Constants.MAX_WORD_CHAT));
		
		int receiver = json.getInt("receiver");
		User userOfSender = userService.getUserById(sender);
		if(userOfSender==null){
			HomiServer.ERROR("userOfSender["+sender+"] not found!");
			return ;
		}
		
		UserExtInfo extInfoOfSender = userService.getUserExtInfoByUserId(sender);
		if(extInfoOfSender==null){
			HomiServer.ERROR("extInfoOfSender["+sender+"] not found!");
			return ;
		}
		
		UserExtInfo extInfoOfReceiver = userService.getUserExtInfoByUserId(receiver);
		if(extInfoOfReceiver==null){
			HomiServer.ERROR("extInfoOfReceiver["+receiver+"] not found!");
			return ;
		}
		
		ChatMessage cm = HomiUtil.makeChatMessage(json,userOfSender,extInfoOfSender,extInfoOfReceiver);
		
		int succ = saveChatMessage(cm);
		
		boolean isFriend = updateContactDetailIfFriend(extInfoOfSender,extInfoOfReceiver);
		
		Session session = sessionService.getSessionByUserId(receiver);
		if(session==null){
			HomiServer.INFO("sendChatMessage by device push.because receiver["+receiver+"] offline.");
			//off line,push if ios device  
			notifyService.addToPushQueue(HomiUtil.makeChatPushMessage(cm,userOfSender));
		}else{
			IoSession ioSession = homiServer.getIoSessionByUserId(receiver);
			if(ioSession!=null){
				HomiProtocol protocol = HomiUtil.makeChatMessageProtocol(cm,isFriend);
				ioSession.write(protocol);
			}
		}
		
		routerChatMessage(cm);
	}
	
	private void routerChatMessage(ChatMessage cm){
		JSONObject routerPack = JSONObject.fromObject(cm);
		routerPack.put("createAt", cm.getCreateAt().getTime());
		routerPack.put("lastLoginAt", cm.getLastLoginAt().getTime());
		routerPack.put("moodUpdateAt", cm.getMoodUpdateAt().getTime());
		HomiProtocol routerProtocol = new HomiProtocol(Helper.genUUID(),TypeCode.MESSAGE_ROUTER_TYPE_CHAT);
		JSONObject routerProtocolJson = new JSONObject();
		routerProtocolJson.accumulate("type", TypeCode.CHAT);
		routerProtocolJson.accumulate("receiver", cm.getReceiver());
		routerProtocolJson.accumulate("content", routerPack);
		routerProtocol.setContent(routerProtocolJson.toString());
		try{
			messageRouter.sendMessage(routerProtocol);
		}catch(Exception e){
			HomiServer.ERROR(e.getMessage(), e);
		}
	}
	
	private boolean updateContactDetailIfFriend(UserExtInfo sender,UserExtInfo receiver){
		Date now = new Date();
		Friend friend = new Friend();
		friend.setUserId(sender.getId());
		friend.setFriendId(receiver.getId());
		friend.setLastContactAt(now);
		friend.setMoodForFriendOfLastContact(receiver.getMood());
		friend.setMoodForMinedOfLastContact(sender.getMood());
		int isFriend = friendService.updateLastContactDetail(friend);
		if(isFriend==1){
			Friend f = new Friend();
			f.setUserId(receiver.getId());
			f.setFriendId(sender.getId());
			f.setLastContactAt(now);
			f.setMoodForFriendOfLastContact(sender.getMood());
			f.setMoodForMinedOfLastContact(receiver.getMood());
			friendService.updateLastContactDetail(f);
			return true;
		}
		
		return false;
	}
}
